package com.example.niuke;

import com.alibaba.fastjson.JSON;

/**
 * 剑指 Offer 56/NC75 - I. 数组中数字出现的次数
 * 一个整型数组 nums 里除两个数字之外，其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n)，空间复杂度是O(1)。
 * <p>
 * 示例 1：
 * <p>
 * 输入：nums = [4,1,4,6]
 * 输出：[1,6] 或 [6,1]
 * 示例 2：
 * <p>
 * 输入：nums = [1,2,10,4,1,4,3,3]
 * 输出：[2,10] 或 [10,2]
 * <p>
 * 思路：异或：相同为0，相异为1。任何数和0异或都是它自己
 * 首先想到如果是求一组数组中只有一个出现一次的数字。那我们进行全局异或即可得到答案，即得到这个数。
 * 由此思路展开，当我们要求两个数字时。只要把这两个数字分到两组，则可类比出现一次的情况来求解
 * 可以依据刚才的思路一直异或，当第一次出现异或后不为0（即第一个出现一次的数字出现了），则停止遍历，换到另一个数组进行。
 */
public class NumberOfArrayI {
    public static void main(String[] args) {
        NumberOfArrayI numberOfArrayI = new NumberOfArrayI();
        int[] a = {4, 1, 4, 6};
        System.out.println(JSON.toJSONString(numberOfArrayI.singleNumbers(a)));
    }

    public int[] singleNumbers(int[] nums) {
        int ret = 0;
        for (int n : nums) {
            ret ^= n;
        }
        int div = 1;
        while ((div & ret) == 0) {
            div <<= 1;
        }
        int a = 0, b = 0;
        for (int n : nums) {
            if ((div & n) != 0) {
                a ^= n;
            } else {
                b ^= n;
            }
        }
        return new int[]{a, b};
    }
}


